import docx
import xml.etree.ElementTree as ET
from zipfile import ZipFile
from collections import defaultdict

# XML 命名空间
NAMESPACES = {
    'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
}

list_mapper = {
    "decimal": [
        "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
        "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38",
        "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50"
    ],
    "lowerLetter": [
        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
        "w", "x", "y", "z", "aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak", "al", "am", "an", "ao",
        "ap", "aq", "ar", "as", "at", "au", "av", "aw", "ax"
    ],
    "upperLetter": [
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
        "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO",
        "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX"
    ],
    "lowerRoman": [
        "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", "xi", "xii", "xiii", "xiv", "xv", "xvi", "xvii",
        "xviii", "xix", "xx", "xxi", "xxii", "xxiii", "xxiv", "xxv", "xxvi", "xxvii", "xxviii", "xxix", "xxx", "xxxi",
        "xxxii", "xxxiii", "xxxiv", "xxxv", "xxxvi", "xxxvii", "xxxviii", "xxxix", "xl", "xli", "xlii", "xliii", "xliv",
        "xlv", "xlvi", "xlvii", "xlviii", "xlix", "l"
    ],
    "upperRoman": [
        "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII",
        "XVIII", "XIX", "XX", "XXI", "XXII", "XXIII", "XXIV", "XXV", "XXVI", "XXVII", "XXVIII", "XXIX", "XXX", "XXXI",
        "XXXII", "XXXIII", "XXXIV", "XXXV", "XXXVI", "XXXVII", "XXXVIII", "XXXIX", "XL", "XLI", "XLII", "XLIII", "XLIV",
        "XLV", "XLVI", "XLVII", "XLVIII", "XLIX", "L"
    ],
    "bullet": [
        "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•",
        "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•", "•",
        "•", "•", "•", "•", "•", "•"
    ],
    "decimalZero": [
        "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18",
        "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36",
        "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50"
    ],
    "cardinalText": [
        "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
        "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty", "twenty-one", "twenty-two",
        "twenty-three", "twenty-four", "twenty-five", "twenty-six", "twenty-seven", "twenty-eight", "twenty-nine",
        "thirty", "thirty-one", "thirty-two", "thirty-three", "thirty-four", "thirty-five", "thirty-six",
        "thirty-seven", "thirty-eight", "thirty-nine", "forty", "forty-one", "forty-two", "forty-three", "forty-four",
        "forty-five", "forty-six", "forty-seven", "forty-eight", "forty-nine", "fifty"
    ],
    "ordinalText": [
        "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh",
        "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth",
        "twentieth", "twenty-first", "twenty-second", "twenty-third", "twenty-fourth", "twenty-fifth", "twenty-sixth",
        "twenty-seventh", "twenty-eighth", "twenty-ninth", "thirtieth", "thirty-first", "thirty-second", "thirty-third",
        "thirty-fourth", "thirty-fifth", "thirty-sixth", "thirty-seventh", "thirty-eighth", "thirty-ninth", "fortieth",
        "forty-first", "forty-second", "forty-third", "forty-fourth", "forty-fifth", "forty-sixth", "forty-seventh",
        "forty-eighth", "forty-ninth", "fiftieth"
    ],
    "ordinal": [
        "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "11th", "12th", "13th", "14th", "15th",
        "16th", "17th", "18th", "19th", "20th", "21st", "22nd", "23rd", "24th", "25th", "26th", "27th", "28th", "29th",
        "30th", "31st", "32nd", "33rd", "34th", "35th", "36th", "37th", "38th", "39th", "40th", "41st", "42nd", "43rd",
        "44th", "45th", "46th", "47th", "48th", "49th", "50th"
    ],
    "chineseCounting": [
        "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二", "十三", "十四", "十五", "十六",
        "十七", "十八", "十九", "二十", "二十一", "二十二", "二十三", "二十四", "二十五", "二十六", "二十七", "二十八",
        "二十九", "三十", "三十一", "三十二", "三十三", "三十四", "三十五", "三十六", "三十七", "三十八", "三十九",
        "四十", "四十一", "四十二", "四十三", "四十四", "四十五", "四十六", "四十七", "四十八", "四十九", "五十"
    ],
    "chineseLegalSimplified": [
        "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾", "拾壹", "拾贰", "拾叁", "拾肆", "拾伍", "拾陆",
        "拾柒", "拾捌", "拾玖", "贰拾", "贰拾壹", "贰拾贰", "贰拾叁", "贰拾肆", "贰拾伍", "贰拾陆", "贰拾柒", "贰拾捌",
        "贰拾玖", "叁拾", "叁拾壹", "叁拾贰", "叁拾叁", "叁拾肆", "叁拾伍", "叁拾陆", "叁拾柒", "叁拾捌", "叁拾玖",
        "肆拾", "肆拾壹", "肆拾贰", "肆拾叁", "肆拾肆", "肆拾伍", "肆拾陆", "肆拾柒", "肆拾捌", "肆拾玖", "伍拾"
    ],
    "ideographDigital": [
        "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二", "十三", "十四", "十五", "十六",
        "十七", "十八", "十九", "二十", "二十一", "二十二", "二十三", "二十四", "二十五", "二十六", "二十七", "二十八",
        "二十九", "三十", "三十一", "三十二", "三十三", "三十四", "三十五", "三十六", "三十七", "三十八", "三十九",
        "四十", "四十一", "四十二", "四十三", "四十四", "四十五", "四十六", "四十七", "四十八", "四十九", "五十"
    ],
    "ideographTraditional": [
        "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖", "拾", "拾壹", "拾貳", "拾叁", "拾肆", "拾伍", "拾陸",
        "拾柒", "拾捌", "拾玖", "貳拾", "贰拾壹", "贰拾貳", "贰拾叁", "贰拾肆", "贰拾伍", "贰拾陸", "贰拾柒", "贰拾捌",
        "贰拾玖", "叁拾", "叁拾壹", "叁拾貳", "叁拾叁", "叁拾肆", "叁拾伍", "叁拾陸", "叁拾柒", "叁拾捌", "叁拾玖",
        "肆拾", "肆拾壹", "肆拾貳", "肆拾叁", "肆拾肆", "肆拾伍", "肆拾陸", "肆拾柒", "肆拾捌", "肆拾玖", "伍拾"
    ],
    "ideographZodiac": [
        "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳",
        "午", "未", "申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥",
        "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", "子", "丑"
    ],
    "ideographEnclosedCircle": [
        "㊀", "㊁", "㊂", "㊃", "㊄", "㊅", "㊆", "㊇", "㊈", "㊉", "(十一)", "(十二)", "(十三)", "(十四)", "(十五)", "(十六)",
        "(十七)", "(十八)", "(十九)", "(二十)", "(二十一)", "(二十二)", "(二十三)", "(二十四)", "(二十五)", "(二十六)",
        "(二十七)", "(二十八)", "(二十九)", "(三十)", "(三十一)", "(三十二)", "(三十三)", "(三十四)", "(三十五)",
        "(三十六)", "(三十七)", "(三十八)", "(三十九)", "(四十)", "(四十一)", "(四十二)", "(四十三)", "(四十四)",
        "(四十五)", "(四十六)", "(四十七)", "(四十八)", "(四十九)", "(五十)"
    ],
    "aiueo": [
        "あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ", "さ", "し", "す", "せ", "そ", "た", "ち", "つ",
        "て", "と", "な", "に", "ぬ", "ね", "の", "は", "ひ", "ふ", "へ", "ほ", "ま", "み", "む", "め", "も", "や",
        "ゆ", "よ", "ら", "り", "る", "れ", "ろ", "わ", "ゐ", "ゑ", "を", "ん", "が", "ぎ"
    ],
    "iroha": [
        "い", "ろ", "は", "に", "ほ", "へ", "と", "ち", "り", "ぬ", "る", "を", "わ", "か", "よ", "た", "れ", "そ",
        "つ", "ね", "な", "ら", "む", "う", "ゐ", "の", "お", "く", "や", "ま", "け", "ふ", "こ", "え", "て", "あ",
        "さ", "き", "ゆ", "め", "み", "し", "ゑ", "ひ", "も", "せ", "す", "い", "ろ", "は"
    ],
    "japaneseCounting": [
        "壱", "弐", "参", "四", "五", "六", "七", "八", "九", "拾", "拾壱", "拾弐", "拾参", "拾四", "拾五", "拾六",
        "拾七", "拾八", "拾九", "弐拾", "弐拾壱", "弐拾弐", "弐拾参", "弐拾四", "弐拾五", "弐拾六", "弐拾七", "弐拾八",
        "弐拾九", "参拾", "参拾壱", "参拾弐", "参拾参", "参拾四", "参拾五", "参拾六", "参拾七", "参拾八", "参拾九",
        "四拾", "四拾壱", "四拾弐", "四拾参", "四拾四", "四拾五", "四拾六", "四拾七", "四拾八", "四拾九", "五拾"
    ],
    "ganada": [
        "가", "나", "다", "라", "마", "바", "사", "아", "자", "차", "카", "타", "파", "하", "거", "너", "더", "러", "머", "버", "서", "어",
        "저", "처", "커", "터", "퍼", "허", "고", "노", "도", "로", "모", "보", "소", "오", "조", "초", "코", "토", "포", "호", "구", "누",
        "두", "루", "무", "부", "수"
    ],
    "chosung": [
        "ㄱ", "ㄴ", "ㄷ", "ㄹ", "ㅁ", "ㅂ", "ㅅ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ", "ㄲ", "ㄸ", "ㅃ", "ㅆ", "ㅉ", "ㄱ", "ㄴ", "ㄷ",
        "ㄹ", "ㅁ", "ㅂ", "ㅅ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ", "ㄲ", "ㄸ", "ㅃ", "ㅆ", "ㅉ", "ㄱ", "ㄴ", "ㄷ", "ㄹ", "ㅁ", "ㅂ",
        "ㅅ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ"
    ],
    "koreanCounting": [
        "일", "이", "삼", "사", "오", "육", "칠", "팔", "구", "십", "십일", "십이", "십삼", "십사", "십오", "십육", "십칠", "십팔", "십구", "이십",
        "이십일", "이십이", "이십삼", "이십사", "이십오", "이십육", "이십칠", "이십팔", "이십구", "삼십", "삼십일", "삼십이", "삼십삼", "삼십사", "삼십오", "삼십육",
        "삼십칠", "삼십팔", "삼십구", "사십", "사십일", "사십이", "사십삼", "사십사", "사십오", "사십육", "사십칠", "사십팔", "사십구", "오십"
    ],
    "vietnameseCounting": [
        "một", "hai", "ba", "bốn", "năm", "sáu", "bảy", "tám", "chín", "mười", "mười một", "mười hai", "mười ba",
        "mười bốn", "mười lăm", "mười sáu", "mười bảy", "mười tám", "mười chín", "hai mươi", "hai mươi mốt",
        "hai mươi hai", "hai mươi ba", "hai mươi bốn", "hai mươi lăm", "hai mươi sáu", "hai mươi bảy", "hai mươi tám",
        "hai mươi chín", "ba mươi", "ba mươi mốt", "ba mươi hai", "ba mươi ba", "ba mươi bốn", "ba mươi lăm",
        "ba mươi sáu", "ba mươi bảy", "ba mươi tám", "ba mươi chín", "bốn mươi", "bốn mươi mốt", "bốn mươi hai",
        "bốn mươi ba", "bốn mươi bốn", "bốn mươi lăm", "bốn mươi sáu", "bốn mươi bảy", "bốn mươi tám", "bốn mươi chín",
        "năm mươi"
    ],
    "decimalFullWidth": [
        "１", "２", "３", "４", "５", "６", "７", "８", "９", "１０", "１１", "１２", "１３", "１４", "１５", "１６", "１７", "１８", "１９", "２０",
        "２１", "２２", "２３", "２４", "２５", "２６", "２７", "２８", "２９", "３０", "３１", "３２", "３３", "３４", "３５", "３６", "３７", "３８",
        "３９", "４０", "４１", "４２", "４３", "４４", "４５", "４６", "４７", "４８", "４９", "５０"
    ],
    "decimalEnclosedCircle": [
        "①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨", "⑩", "⑪", "⑫", "⑬", "⑭", "⑮", "⑯", "⑰", "⑱", "⑲", "⑳", "(21)",
        "(22)", "(23)", "(24)", "(25)", "(26)", "(27)", "(28)", "(29)", "(30)", "(31)", "(32)", "(33)", "(34)", "(35)",
        "(36)", "(37)", "(38)", "(39)", "(40)", "(41)", "(42)", "(43)", "(44)", "(45)", "(46)", "(47)", "(48)", "(49)",
        "(50)"
    ],
    "decimalEnclosedParen": [
        "(1)", "(2)", "(3)", "(4)", "(5)", "(6)", "(7)", "(8)", "(9)", "(10)", "(11)", "(12)", "(13)", "(14)", "(15)",
        "(16)", "(17)", "(18)", "(19)", "(20)", "(21)", "(22)", "(23)", "(24)", "(25)", "(26)", "(27)", "(28)", "(29)",
        "(30)", "(31)", "(32)", "(33)", "(34)", "(35)", "(36)", "(37)", "(38)", "(39)", "(40)", "(41)", "(42)", "(43)",
        "(44)", "(45)", "(46)", "(47)", "(48)", "(49)", "(50)"
    ],
    "decimalEnclosedFullstop": [
        "1.", "2.", "3.", "4.", "5.", "6.", "7.", "8.", "9.", "10.", "11.", "12.", "13.", "14.", "15.", "16.", "17.",
        "18.", "19.", "20.", "21.", "22.", "23.", "24.", "25.", "26.", "27.", "28.", "29.", "30.", "31.", "32.", "33.",
        "34.", "35.", "36.", "37.", "38.", "39.", "40.", "41.", "42.", "43.", "44.", "45.", "46.", "47.", "48.", "49.",
        "50."
    ],
    "numberInDash": [
        "- 1 -", "- 2 -", "- 3 -", "- 4 -", "- 5 -", "- 6 -", "- 7 -", "- 8 -", "- 9 -", "- 10 -", "- 11 -", "- 12 -",
        "- 13 -", "- 14 -", "- 15 -", "- 16 -", "- 17 -", "- 18 -", "- 19 -", "- 20 -", "- 21 -", "- 22 -", "- 23 -",
        "- 24 -", "- 25 -", "- 26 -", "- 27 -", "- 28 -", "- 29 -", "- 30 -", "- 31 -", "- 32 -", "- 33 -", "- 34 -",
        "- 35 -", "- 36 -", "- 37 -", "- 38 -", "- 39 -", "- 40 -", "- 41 -", "- 42 -", "- 43 -", "- 44 -", "- 45 -",
        "- 46 -", "- 47 -", "- 48 -", "- 49 -", "- 50 -"
    ],
    "hex": [
        "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "10", "11", "12", "13", "14", "15",
        "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26", "27",
        "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31", "32"
    ],
    "russianLower": [
        "а", "б", "в", "г", "д", "е", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х",
        "ц", "ч", "ш", "щ", "ъ", "ы", "ь", "э", "ю", "я", "аа", "аб", "ав", "аг", "ад", "ае", "аж", "аз", "аи", "ай",
        "ак", "ал", "ам", "ан", "ао", "ап", "ар"
    ],
    "russianUpper": [
        "А", "Б", "В", "Г", "Д", "Е", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х",
        "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я", "АА", "АБ", "АВ", "АГ", "АД", "АЕ", "АЖ", "АЗ", "АИ", "АЙ",
        "АК", "АЛ", "АМ", "АН", "АО", "АП", "АР"
    ],
    "hebrew1": [
        "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט", "י", "יא", "יב", "יג", "יד", "טו", "טז", "יז", "יח", "יט", "כ",
        "כא", "כב", "כג", "כד", "כה", "כו", "כז", "כח", "כט", "ל", "לא", "לב", "לג", "לד", "לה", "לו", "לז", "לח", "לט",
        "מ", "מא", "מב", "מג", "מד", "מה", "מו", "מז", "מח", "מט", "נ"
    ],
    "arabicAbjad": [
        "أ", "ب", "ج", "د", "ه", "و", "ז", "ח", "ט", "ي", "يا", "يب", "يج", "يد", "يه", "يو", "יז", "יח", "יט", "ك",
        "كا", "כב", "כג", "כד", "כה", "כו", "כז", "כח", "כט", "ل", "لا", "לב", "לג", "לד", "לה", "לו", "לז", "לח", "לט",
        "מ", "מא", "מב", "מג", "מד", "מה", "מו", "מז", "מח", "מט", "נ"
    ],
    "thaiNumbers": [
        "๑", "๒", "๓", "๔", "๕", "๖", "๗", "๘", "๙", "๑๐", "๑๑", "๑๒", "๑๓", "๑๔", "๑๕", "๑๖", "๑๗", "๑๘", "๑๙", "๒๐",
        "๒๑", "๒๒", "๒๓", "๒๔", "๒๕", "๒๖", "๒๗", "๒๘", "๒๙", "๓๐", "๓๑", "๓๒", "๓๓", "๓๔", "๓๕", "๓๖", "๓๗", "๓๘",
        "๓๙", "๔๐", "๔๑", "๔๒", "๔๓", "๔๔", "๔๕", "๔๖", "๔๗", "๔๘", "๔๙", "๕๐"
    ],
    "hindiNumbers": [
        "१", "२", "३", "४", "५", "६", "७", "८", "९", "१०", "११", "१२", "१३", "१४", "१५", "१६", "१७", "१८", "१९", "२०",
        "२१", "२२", "२۳", "२४", "२५", "२६", "२७", "२८", "२९", "३०", "३१", "३२", "३३", "३४", "३५", "३६", "३७", "३८",
        "३९", "४०", "४१", "४२", "४३", "४४", "४५", "४६", "४७", "४८", "४९", "५०"
    ],
    "none": [
        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
    ],
    "未知": [
        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
        "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
    ]
}


def get_numbering_definitions_with_text_format(docx_path):
    definitions = {}
    with ZipFile(docx_path, 'r') as zip_file:
        if 'word/numbering.xml' not in zip_file.namelist():
            return {}
        with zip_file.open('word/numbering.xml') as f:
            tree = ET.parse(f)
            root = tree.getroot()

            abstract_num_map = {}
            for abstract_num in root.findall('w:abstractNum', NAMESPACES):
                abstract_num_id = abstract_num.get(f"{{{NAMESPACES['w']}}}abstractNumId")
                level_map = {}
                for lvl in abstract_num.findall('w:lvl', NAMESPACES):
                    ilvl = lvl.get(f"{{{NAMESPACES['w']}}}ilvl")
                    # 获取数字格式 (decimal, letter等.)
                    num_fmt_element = lvl.find('w:numFmt', NAMESPACES)
                    num_fmt = num_fmt_element.get(
                        f"{{{NAMESPACES['w']}}}val") if num_fmt_element is not None else 'none'
                    # 获取完整的文本格式模板
                    lvl_text_element = lvl.find('w:lvlText', NAMESPACES)
                    lvl_text = lvl_text_element.get(f"{{{NAMESPACES['w']}}}val") if lvl_text_element is not None else ''

                    level_map[ilvl] = {'format': num_fmt, 'text_format': lvl_text}

                abstract_num_map[abstract_num_id] = level_map

            for num in root.findall('w:num', NAMESPACES):
                num_id = num.get(f"{{{NAMESPACES['w']}}}numId")
                abstract_num_id_element = num.find('w:abstractNumId', NAMESPACES)
                if abstract_num_id_element is not None:
                    abstract_num_id = abstract_num_id_element.get(f"{{{NAMESPACES['w']}}}val")
                    if abstract_num_id in abstract_num_map:
                        definitions[num_id] = abstract_num_map[abstract_num_id]

    return definitions


def analyze_lists_with_custom_text(docx_path):
    try:
        # 获取包含完整文本格式的编号定义
        numbering_definitions = get_numbering_definitions_with_text_format(docx_path)
        document = docx.Document(docx_path)
        lists_by_id = defaultdict(list)

        for p in document.paragraphs:
            num_pr = p._p.pPr.numPr if p._p.pPr is not None else None
            if num_pr is not None:
                ilvl_element = num_pr.find(docx.oxml.ns.qn('w:ilvl'))
                num_id_element = num_pr.find(docx.oxml.ns.qn('w:numId'))

                if ilvl_element is not None and num_id_element is not None:
                    ilvl_str = str(ilvl_element.val)
                    num_id_str = str(num_id_element.val)

                    # 查询详细格式信息
                    format_info = numbering_definitions.get(num_id_str, {}).get(ilvl_str, {})
                    fmt = format_info.get('format', '未知')
                    text_format = format_info.get('text_format', '')
                    item_data = {
                        "level": int(ilvl_str) + 1,
                        "format": fmt,
                        "text_format": text_format,
                        "text": p.text,
                    }
                    lists_by_id[num_id_str].append(item_data)

        print(f"成功加载并分析文件: {docx_path}")
        if not lists_by_id:
            print("\n文档中未检测到自动编号列表。")
            return

        print(f"\n在文档中总共检测到 {len(lists_by_id)} 个独立的列表。\n")

        for num_id, items in lists_by_id.items():
            print(f"检测到列表 (numId: {num_id})")
            level_index = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            level_mapper = {}
            for item in items:
                indent = "  " * (item['level'] - 1)
                if item['level'] > 16:
                    full_text = item['text']
                else:
                    current_list_index = list_mapper[item['format']][level_index[item['level'] - 1]]
                    level_mapper[f'%{item['level']}'] = current_list_index
                    full_text = item['text_format'] + item['text']
                    for level_map in level_mapper.keys():
                        full_text = full_text.replace(level_map,level_mapper[level_map])
                    # full_text = item['text_format'].replace(f'%{item['level']}', current_list_index) + item['text']
                    level_index[item['level'] - 1] += 1
                print(
                    f"{indent}级别: {item['level']}, "
                    f"文本格式: '{item['text_format']}', "
                    f"数字类型: '{item['format']}', "
                    f"全文本: {full_text}"
                )

            print()

    except Exception as e:
        import traceback
        print(f"处理文件时出错: {e}")
        traceback.print_exc()

if __name__ == "__main__":
    file_path = "新建 Microsoft Word 文档 (2).docx"
    analyze_lists_with_custom_text(file_path)
